#ifndef _LINK_STACK_H_
#define _LINK_STACK_H_

#include "Stack.h"
#include "LinkList.h"
#include "Exception.h"

namespace MySTL
{

template < typename T >
class LinkStack : public Stack<T>
{
public:
	~LinkStack();

	bool push(const T& value);
	T pop();
	T& top();
	const T& top() const;
	void clear();
	int length() const;

protected:
	LinkList<T> m_list;
};

template < typename T >
LinkStack<T>::~LinkStack()
{
	m_list.clear();
}

template < typename T >
bool LinkStack<T>::push(const T& value)
{
	return m_list.insert(0, value);
}

template < typename T >
T LinkStack<T>::pop()
{
	if (m_list.length() <= 0)
	{
		THROW_EXCEPTION(InvalidOperationException, "Invalid operate in T LinkStack<T>::pop()");
	}

	T ret = m_list[0];

	m_list.remove(0);

	return ret;
}

template < typename T >
T& LinkStack<T>::top()
{
	if (m_list.length() <= 0)
	{
		THROW_EXCEPTION(InvalidOperationException, "Invalid operate in T& LinkStack<T>::top()");
	}

	return m_list[0];
}

template < typename T >
const T& LinkStack<T>::top() const
{
	return const_cast<LinkStack<T>*>(this)->top();
}

template < typename T >
void LinkStack<T>::clear()
{
	m_list.clear();
}

template < typename T >
int LinkStack<T>::length() const
{
	return m_list.length();
}

}

#endif